React 文档
导读与全书目录表:见同目录 01-React 入门:简介·特性与设计范式.md 开头。
说说你对 react fiber 架构的理解?
回答
shell
从解决了什么痛点问题、核心设计思想、以及如何实现三个方向回答此问题
# 解决的痛点问题
在 React 15 及以前,使用的是 Stack Reconciler(栈协调器)。它的更新流程是同步且递归的,就像一个很深的函数调用栈,一旦开始更新就必须一口气把整棵 Virtual DOM 树 Diff 完,直到更新结束。
这就导致了一个问题:如果组件树非常庞大,计算 Diff 的时间超过了浏览器一帧的时间(通常是 16.6ms,即 60fps),主线程就会被 JS 运算一直占用。在此期间,用户的点击、输入、页面动画都无法得到及时响应,造成页面卡顿、掉帧。
Fiber 架构就是为了解决这个 “同步更新阻塞主线程” 的问题而生的。
# 核心设计思想
它不再像以前那样一次性递归处理整棵树,而是把更新任务拆分成了一个个微小的执行单元(叫做 Fiber 节点)。React 利用浏览器的空闲时间(后来自己实现了 Scheduler)去执行这些小单元,每执行完一个就检查一下:有没有剩余时间?有没有更高优先级的任务(比如用户点击)?如果时间不够或有急事,就暂停当前任务,把主线程还给浏览器;等下一次空闲时再恢复之前的任务继续执行。这就保证了页面始终是流畅的。
# 实现
第一,Fiber 数据结构(链表树)。
React 放弃了以前的递归栈,改用链表来遍历组件树。每个组件对应一个 Fiber 节点,节点里包含了 child(大儿子)、sibling(兄弟)、return(父级)等指针。这种链表结构让 React 可以随时中断遍历,也能随时从断点处恢复,非常灵活。
第二,双缓存技术(Current 树与 WorkInProgress 树)。
内存中同时存在两棵树:一棵是当前屏幕上显示的 current 树,另一棵是正在后台构建的 workInProgress 树。所有的更新都在 workInProgress 树上进行,构建完成后直接互换指针,完成视图切换。这既避免了频繁操作 DOM,也保证了中断 / 恢复时的数据一致性。
第三,优先级调度。
Fiber 给不同的更新分了三六九等(比如用户点击输入的优先级最高,数据请求回来的更新次之)。React 会优先处理高优先级的任务,确保用户的交互能得到最快的响应,而不是所有任务排队 FIFO。
总结一下,Fiber 架构通过 “时间切片” 和 “优先级调度”,让 React 从一个 “霸道的占线者” 变成了一个 “礼貌的协作者”,极大提升了复杂应用的流畅度和用户体验。”拓展
shell
# 时间切片是怎么实现的?是用 requestIdleCallback 吗?
早期是,但因为兼容性和触发频率不稳定,React 后来自己基于 MessageChannel 实现了 Scheduler 调度器,在宏任务中模拟时间切片。
# Render 阶段和 Commit 阶段的区别
Render 阶段(构建 Fiber 树、打 Diff 标记)是可中断的;Commit 阶段(操作 DOM、执行生命周期)是不可中断的,必须一气呵成,否则页面会显示不一致。React 的 Fiber 架构解决了什么问题?核心设计思路是什么?
回答
shell
# 总结
Fiber 本质是「可中断的工作单元」,通过任务拆分和优先级调度,让 React 能在复杂场景下保持 UI 响应性,核心是将同步渲染改为异步可中断渲染。
# 解决了
解决了 React 15 中栈协调器(Stack Reconciler)无法中断、递归更新导致的页面卡顿问题,支持任务分片和优先级调度。
# 原理、核心设计思路
把渲染任务拆分成小单元(Fiber 节点),每个单元可独立暂停、恢复、中断。
采用单链表结构存储 Fiber 节点,通过指针(child/sibling/return)实现遍历,替代递归,避免调用栈过深。
配合调度器(Scheduler),根据任务优先级(如用户输入 > 动画 > 数据请求)分配执行时机,浏览器空闲时执行,避免阻塞主线程。React协调阶段和提交阶段的区别?每个阶段都做了什么?
回答
shell
# 总结
协调是「决策阶段」,确定要做什么;commit 是「执行阶段」,真正操作 DOM。这种分离让 React 能在协调阶段灵活调度,提升性能。
# 区别
协调是「计算差异」,commit 是「执行 DOM 操作」;协调可中断,commit 不可中断。
# 原理/每个阶段都做了什么
协调阶段:通过 Diff 算法对比新旧虚拟 DOM,找出需要更新的节点(增删改),标记节点操作类型(Placement/Update/Deletion),生成 Effect List(待执行的副作用队列)。此阶段在内存中完成,可被高优先级任务中断。
commit 阶段:根据 Effect List 执行实际 DOM 操作(插入 / 更新 / 删除),并调用生命周期钩子(如 componentDidMount)和 Hooks(如 useEffect)。此阶段直接操作 DOM,必须同步执行,不可中断。并发模式(Concurrent Mode)核心思想?如何优化用户体验?
回答
shell
# 总结
并发模式是 React 从「同步渲染」到「异步可中断渲染」的核心演进,通过优先级调度确保用户交互的流畅性,尤其在复杂 UI 和大数据渲染场景下提升明显。
# 核心思想
传统模式中渲染是同步且不可中断的,长时间任务会阻塞用户输入(如点击、滚动)。
并发模式下,React 可同时准备多个 UI 版本(如用户输入的紧急更新和列表渲染的低优先级更新),根据优先级切换,保证高优先级任务(如输入)优先完成,避免卡顿。
# 如何优化用户体验
配合 Suspense、useTransition 等 API,实现「加载中不阻塞交互」。React 18 有哪些新特性?
回答
shell
核心新特性:
① 并发渲染(Concurrent Rendering):非阻塞渲染,比如渲染大列表时不卡页面;
② 自动批处理(Automatic Batching):把多个 setState 合并成一次渲染,提升性能;
③ Suspense:支持数据请求的加载状态(配合 React.lazy 做代码分割,也能等数据加载);
④ 新的 root API:createRoot 替代 ReactDOM.render,支持并发特性;
总结:React 18 核心是 “并发”,让渲染更灵活、性能更好。React 18 重要新特性:automatic batching、transitions
回答
shell
# 总结
automatic batching 自动批量更新状态,transitions 区分紧急和非紧急更新,提升响应性。
React 18 进一步强化了并发特性,automatic batching 减少不必要的渲染,transitions 让开发者能主动区分任务优先级,两者结合显著提升复杂交互场景的用户体验。
# 原理
automatic batching:React 18 中,无论在合成事件、setTimeout 还是 Promise 中,setState 都会自动批量合并,减少重渲染(React 17 中仅合成事件批量更新)。
transitions:通过 useTransition 标记非紧急更新(如列表筛选),React 会优先处理紧急更新(如输入框输入),非紧急更新可被中断,避免页面卡顿。适合「用户输入 + 结果渲染」场景。